﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data.SqlClient;
using System.Data;
using TSL_Tools.SqlTools;
using ReportingEngine;
using System.Xml;
using System.Xml.Linq;
using System.IO;

namespace VSLT_Reporting
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private StringBuilder debugTimingInfo = new StringBuilder();

        private void AddDebugTimingInfo(TimeSpan ts, string message)
        {
            StringBuilder sTemp = new StringBuilder();            
            foreach (string str in message.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries))
            {
                sTemp.Append(str.Trim());
            }
        
            debugTimingInfo.AppendLine(String.Format("{0} seconds: \t{1}"
                , ts.TotalSeconds.ToString("N2")
                , sTemp.ToString()));

        }
    }

    public class Logging
    {
        public StringBuilder debugTimingInfoString { get; set; }
        public DataTable debugTimingInfoTable { get; set; }
        public LoggingLevel level { get; set; }

        private bool bUseDataTable = false;

        #region -- Constructors ---------------------------------------------------------------------------
        /// <summary>
        /// This initializes the logging level to 'Summary' and creates a new StringBuilder instance to store the data. 
        /// StringBuilder to store the data. 
        /// </summary>
        public Logging()
        {
            level = LoggingLevel.Summary;
            debugTimingInfoString = new StringBuilder();
        }

        /// <summary>
        /// This initializes the logging level to the passed in value and creates a new StringBuilder instance to store the data. 
        /// </summary>
        /// <param name="loggingLevel">The <see cref="LoggingLevel"/> to use for tracking the amount of info to log</param>
        public Logging(LoggingLevel loggingLevel)
        {
            level = loggingLevel;
            debugTimingInfoString = new StringBuilder();
        }

        /// <summary>
        /// This initializes the logging level to the passed in value and creates a new StringBuilder instance to store the data. 
        /// </summary>
        /// <param name="loggingLevel">The <see cref="LoggingLevel"/> to use for tracking the amount of info to log</param>
        /// <param name="useDataTable">if true, a new DataTable Instance is created. If false, a new StringBuilder instance is created.</param>
        public Logging(LoggingLevel loggingLevel, bool useDataTable)
        {
            level = loggingLevel;
            if (useDataTable)
            {
                debugTimingInfoTable = new DataTable();
                bUseDataTable = true;
                InitializeDebugTimingInfoTable();
            }
            else
            {
                debugTimingInfoString = new StringBuilder();
            }
        }
        #endregion

        #region -- Initialization routines ---------------------------------------------------------------
        private void InitializeDebugTimingInfoTable()
        {
            debugTimingInfoTable.Columns.Add("TimeTaken");
            debugTimingInfoTable.Columns.Add("Calling Method");
            debugTimingInfoTable.Columns.Add("Details");
        }

        public void ResetDebugTimingInfo()
        {
            if (bUseDataTable)
                debugTimingInfoTable.Rows.Clear();
            else
                debugTimingInfoString.Clear();
        }
        #endregion

        #region -- Add Info routines ---------------------------------------------------------------------
        /// <summary>
        /// Adds the info to the appropriate logging object using a default logging level of 'Summary'
        /// </summary>
        /// <param name="ts">The TimeSpan to add to the log entry</param>
        /// <param name="message">The string message to add to the log entry</param>
        /// <param name="callingMethod">[OPTIONAL] The name of the method logging the entry</param>
        public void AddDebugTimingInfo(TimeSpan ts, string message, string callingMethod = "")
        {
            AddDebugTimingInfo(LoggingLevel.Summary, ts, message, callingMethod);
        }

        /// <summary>
        /// Adds the info to the appropriate logging object using a default logging level of 'Summary'
        /// </summary>
        /// <param name="loggingLevel">The <see cref="LoggingLevel"/> to use for tracking the amount of info to log</param>
        /// <param name="ts">The TimeSpan to add to the log entry</param>
        /// <param name="message">The string message to add to the log entry</param>
        /// <param name="callingMethod">[OPTIONAL] The name of the method logging the entry</param>
        public void AddDebugTimingInfo(LoggingLevel loggingLevel, TimeSpan ts, string message, string callingMethod = "")
        {
            if (bUseDataTable)
                AddDebugTimingInfoRow(ts, message, callingMethod);
            else
                AddDebugTimingInfoLine(ts, message);
        }

        private void AddDebugTimingInfoLine(TimeSpan ts, string message)
        {
            StringBuilder sTemp = new StringBuilder();
            foreach (string str in message.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries))
            {
                sTemp.Append(str.Trim());
            }
            debugTimingInfoString.AppendLine(String.Format("{0} seconds: \t{1}", ts.TotalSeconds.ToString("N2"), sTemp.ToString()));
        }

        private void AddDebugTimingInfoRow(TimeSpan ts, string message, string callingMethod)
        {
            StringBuilder sTemp = new StringBuilder();
            foreach (string str in message.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries))
            {
                sTemp.Append(str.Trim());
            }

            debugTimingInfoTable.Rows.Add(ts.TotalSeconds.ToString("N2"), callingMethod, sTemp.ToString());
        }
        #endregion
    }

    /// <summary>
    /// Defines the level of logging that will occur
    /// </summary>
    public enum LoggingLevel
    {
        /// <summary>
        /// Nothing is output
        /// </summary>
        None = 0,

        /// <summary>
        /// Output only errors
        /// </summary>
        Error = 1,

        /// <summary>
        /// Output errors and summary info
        /// </summary>
        Summary = 5,

        /// <summary>
        /// Output all messages except debug statements
        /// </summary>
        Detailed = 10,
        
        /// <summary>
        /// Output all messages
        /// </summary>
        Debug = 15
    };
}
